//! 系统心跳管理

use alloc::sync::Arc;
use core::{
    sync::atomic::{AtomicU64, Ordering},
    time::Duration,
};

use crate::{
    bsp::__system_tick,
    irq::irqflags::{local_irq_restore, local_irq_save},
    processor::this_processor_id,
    time::{
        hrtimer::{Hrtimer, HrtimerMode, HrtimerRestart, hrtimer_start},
        timekeeping::update_wall_time,
    },
};

static JIFFIES: AtomicU64 = AtomicU64::new(0);
static PERIODIC_NS: AtomicU64 = AtomicU64::new(0);

/// 系统心跳计数
pub fn jiffies() -> u64 {
    JIFFIES.load(Ordering::Relaxed)
}

fn tick_periodic(timer: &Hrtimer) -> HrtimerRestart {
    if this_processor_id() == 0 {
        JIFFIES.fetch_add(1, Ordering::Relaxed);
        update_wall_time();
    }
    let periodic_ns = PERIODIC_NS.load(Ordering::Relaxed);
    timer.forward_now(periodic_ns);
    HrtimerRestart::Restart
}

pub(super) fn system_tick_init_cpu() {
    let periodic_ms = unsafe { __system_tick() as u64 };
    let periodic_ns = Duration::from_millis(periodic_ms).as_nanos() as u64;
    let flags = local_irq_save();
    let timer = Hrtimer::create(HrtimerMode::Rel, tick_periodic, None);
    PERIODIC_NS.store(periodic_ns, Ordering::Relaxed);
    hrtimer_start(Arc::new(timer), periodic_ns);
    local_irq_restore(flags);
}
